package cn.okcmd.base;

import lombok.extern.slf4j.Slf4j;

/**
 * create by caoqg on 2021/7/17
 * 功能说明:
 */
@Slf4j
public class TestClassLoader {

    public static void main(String[] args) {
        testCLParent();

        log.info("========以下为BootClassLoader加载内容=============");
        /**
         * 启动（Bootstrap）类加载器：启动类加载器是用本地代码实现的类加载器，
         * 它负责将JAVA_HOME/lib下面的核心类库或-Xbootclasspath选项指定的jar包等虚拟机识别的类库加载到内存中。
         * 由于启动类加载器涉及到虚拟机本地实现细节，开发者无法直接获取到启动类加载器的引用。
         * 具体可由启动类加载器加载到的路径可通过System.getProperty(“sun.boot.class.path”)查看
         */

        String bootPathKey = "sun.boot.class.path";
        String bootPath = System.getProperty(bootPathKey);
        String[] allBootJars = bootPath.split(":");
        for (int i = 0; i < allBootJars.length; i++) {
            log.info("bootLoader load index:[{}] jar:{}", i + 1, allBootJars[i]);
        }

        /**
         * 扩展（Extension）类加载器：扩展类加载器是由Sun的ExtClassLoader（sun.misc.Launcher$ExtClassLoader）实现的，
         * 它负责将JAVA_HOME /lib/ext或者由系统变量-Djava.ext.dir指定位置中的类库加载到内存中。
         * 开发者可以直接使用标准扩展类加载器，
         * 具体可由扩展类加载器加载到的路径可通过System.getProperty("java.ext.dirs")查看。
         */
        log.info("========以下为ExtClassLoader加载内容=============");
        String extPathKey="java.ext.dirs";
        String extPath = System.getProperty(extPathKey);
        String[] extLoadJars = extPath.split(":");
        for (int i = 0; i < extLoadJars.length; i++) {
            log.info("ExtClassLoader load index:[{}] jar:{}",i+1,extLoadJars[i]);
        }

        /**
         * 系统（System）类加载器：系统类加载器是由 Sun 的 AppClassLoader（sun.misc.Launcher$AppClassLoader）实现的，
         * 它负责将用户类路径(java -classpath或-Djava.class.path变量所指的目录，
         * 即当前类所在路径及其引用的第三方类库的路径，如第四节中的问题6所述)下的类库加载到内存中。
         * 开发者可以直接使用系统类加载器，具体可由系统类加载器加载到的路径可通过System.getProperty("java.class.path")查看。
         */
        log.info("========以下为AppClassLoader加载内容=============");
        String appPathKey="java.class.path";
        String appPath = System.getProperty(appPathKey);
        String[] appLoadJars = appPath.split(":");
        for (int i = 0; i < appLoadJars.length; i++) {
            log.info("AppClassLoader load index:[{}] jar:{}",i+1,appLoadJars[i]);
        }
    }



    private static void testCLParent() {
        ClassLoader appLoader = TestClassLoader.class.getClassLoader();
        log.info("appLoad:{}",appLoader);
        ClassLoader extLoader = appLoader.getParent();
        log.info("extLoad:{}",extLoader);
        ClassLoader bootLoader = extLoader.getParent();
        log.info("bootLoad:{}",bootLoader);
    }

}
